<?php

use think\facade\Cache;

/**
 * 对查询结果集进行排序
 * @access public
 * @param array $list 查询结果
 * @param string $field 排序的字段名
 * @param array $sortby 排序类型
 * asc正向排序 desc逆向排序 nat自然排序
 * @return array
 */
function list_sort_by($list,$field, $sortby='asc') {
    if(is_array($list)){
        $refer = $resultSet = array();
        foreach ($list as $i => $data)
            $refer[$i] = &$data[$field];
        switch ($sortby) {
            case 'asc': // 正向排序
                asort($refer);
                break;
            case 'desc':// 逆向排序
                arsort($refer);
                break;
            case 'nat': // 自然排序
                natcasesort($refer);
                break;
        }
        foreach ( $refer as $key=> $val)
            $resultSet[] = &$list[$key];
        return $resultSet;
    }
    return false;
}
// 应用公共文件
/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pid parent标记字段
 * @param string $level level标记字段
 * @return array
 */
function list_to_tree($list, $pk='id', $pid = 'pid', $child = '_child', $root = 0) {
    // 创建Tree
    $tree = array();
    if(is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] =& $list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId =  $data[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            }else{
                if (isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 将list_to_tree的树还原成列表
 * @param  array $tree  原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array  $list  过渡用的中间数组，
 * @return array        返回排过序的列表数组
 */
function tree_to_list($tree, $child = '_child', $order='id', &$list = array()){
    if(is_array($tree)) {
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if(isset($reffer[$child])){
                unset($reffer[$child]);
                tree_to_list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
        $list = list_sort_by($list, $order, $sortby='asc');
    }
    return $list;
}



function is_administrator($uid = null){
    $uid = is_null($uid) ? session("uid") : $uid;
    return $uid && (intval($uid) === (int)config('global.USER_ADMINISTRATOR'));
}

/**
 * 字符串转数组
 * @param $str
 * @param $glue
 * @return string[]
 */
function str2arr($str, $glue = ','){
    return explode($glue, $str);
}


function domain_upload_url($url) {
    $default = config("filesystem.default");
    $disk = config("filesystem.disks")[$default];

}

function cmf_get_current_admin_id()
{
    return session('uid');
}


function create_log_id()
{
    if (defined('LOG_ID')) {
        return LOG_ID;
    }
    if (!empty($_SERVER['HTTP_X_BD_LOGID']) && intval(trim($_SERVER['HTTP_X_BD_LOGID'])) !== 0) {
        define('LOG_ID', trim($_SERVER['HTTP_X_BD_LOGID']));
    } elseif (isset($_REQUEST['log_id']) && intval($_REQUEST['log_id']) !== 0) {
        define('LOG_ID', intval($_REQUEST['log_id']));
    } else {
        $arr = gettimeofday();
        $logId = ((($arr['sec'] * 100000 + intval($arr['usec'] / 10)) & 0x7FFFFFFF) | 0x80000000);
        define('LOG_ID', $logId);
    }
    return LOG_ID;
}

// 分析枚举类型配置值 格式 a:名称1,b:名称2
function parse_config_attr($string) {
    $array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
    if(strpos($string,':')){
        $value  =   array();
        foreach ($array as $val) {
            list($k, $v) = explode(':', $val);
            $value[$k]   = $v;
        }
    }else{
        $value  =   $array;
    }
    return $value;
}

// 不区分大小写的in_array实现
function in_array_case($value, $array) {
    return in_array(strtolower($value), array_map('strtolower', $array));
}

/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 */
function format_bytes($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}
/**
 * 字符串命名风格转换
 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
 * @param string  $name    字符串
 * @param integer $type    转换类型
 * @param bool    $ucfirst 首字母是否大写（驼峰规则）
 * @return string
 */
function h_parse_name($name, $type = 0, $ucfirst = true)
{
    if ($type) {
        $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
            return strtoupper($match[1]);
        }, $name);
        return $ucfirst ? ucfirst($name) : lcfirst($name);
    }

    return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
}



/**
 * 添加钩子
 * @param string $hook   钩子名称
 * @param mixed  $params 传入参数
 * @param bool   $once
 * @return mixed
 */
function hook($hook, $params = null, $once = false)
{
    $hook = h_parse_name($hook, 1);
    return \think\facade\Event::trigger($hook, $params, $once);
}

/**
 * 添加钩子,只执行一个
 * @param string $hook   钩子名称
 * @param mixed  $params 传入参数
 * @return mixed
 */
function hook_one($hook, $params = null)
{
    $hook = h_parse_name($hook, 1);
    return \think\facade\Event::trigger($hook, $params, true);
}

/**
 * 替代scan_dir的方法
 * @param string $pattern 检索模式 搜索模式 *.txt,*.doc; (同glog方法)
 * @param int    $flags
 * @param        $pattern
 * @return array
 */
function h_scan_dir($pattern, $flags = 0)
{
    $files = glob($pattern, $flags);
    if (empty($files)) {
        $files = [];
    } else {
        $files = array_map('basename', $files);
    }

    return $files;
}

/**
 * 获取插件类的类名
 * @param strng $name 插件名
 */
function get_service_class($name){
    $name = ucfirst($name);
    $service = "app\service\\{$name}Service";
    if (!class_exists($service)) {
        throw new \Exception("{$name} service not found");
    }
    return app()->make($service);
}

function t($message) {
    $request = app()->request;
    $lang = "zh-CN";
    $range = $request->header("api-lang");
    $accept_language = $request->header('accept-language');
    if (!empty($accept_language)) {
        $lang  = explode(',', $request->header('accept-language'))[0];
    }
    if (!empty($range)) {
        $lang =$range;
    }
    $data = include_once LANG_PATH.DS.strtolower("$lang.php");

    return $data[$message] ?? $message;
}

function h_encrypt($data, $key = '', $expire = 0) {
    $key  = md5(empty($key) ? config("app.data_auth_key") : $key);
    $data = base64_encode($data);
    $x    = 0;
    $len  = strlen($data);
    $l    = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time():0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
    }
    return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
}

/**
 * 系统解密方法
 * @param  string $data 要解密的字符串 （必须是think_encrypt方法加密的字符串）
 * @param  string $key  加密密钥
 * @return string
 */
function h_decrypt($data, $key = ''){
    $key    = md5(empty($key) ? config("app.data_auth_key") : $key);
    $data   = str_replace(array('-','_'),array('+','/'),$data);
    $mod4   = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data   = base64_decode($data);
    $expire = substr($data,0,10);
    $data   = substr($data,10);

    if($expire > 0 && $expire < time()) {
        return '';
    }
    $x      = 0;
    $len    = strlen($data);
    $l      = strlen($key);
    $char   = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        }else{
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

function h_create_order_no ($prefix="") {
  return strtoupper($prefix).date('Ymd') . substr(implode("", array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}

function int_to_string(&$data,$map=array('status'=>array(1=>'正常',-1=>'禁用',0=>'审核中'))) {
    if($data === false || $data === null ){
        return $data;
    }
    $data = (array)$data;
    foreach ($data as $key => $row){
        foreach ($map as $col=>$pair){
            if(isset($row[$col]) && isset($pair[$row[$col]])){
                $data[$key][$col.'_text'] = $pair[$row[$col]];
            }
        }
    }
    return $data;
}

/**
 * 获取客服url
 * @return void
 */
function h_get_customer_url() {
     $id = session("mid");
     if (!$id) {
         return config("global.CHART_LINK");
     }
     $service = app()->make(\app\service\MemberService::class);
     $customerLink = $service->value(["id"=>$id],"customer_link");
     return $customerLink ? $customerLink:config("global.CHART_LINK");
}


function h_format_large_number($number) {
    // 转换为浮点型，确保数字有效性
     if ($number>1) {
         return number_format($number,3);
     }
     return $number;
}

function h_money_switch($code,$amount) {
    $redisKey = sprintf("market.%susdt.kline.1sec",$code);
    if ($code!="usdt") {
        $data = Cache::store('redis')->get($redisKey);
        $amount =  floatval($amount)*$data["close"];
    }
    return round($amount,2);
}

function h_now_price($code) {
    $redisKey = sprintf("market.%susdt.kline.1sec",$code);
    $data = Cache::store('redis')->get($redisKey);
    return $data["close"];
}

/**
 * 字符串中间四位替换为*号
 * @param string $str 原始字符串
 * @return string 处理后的字符串
 */
function h_mask($str) {
    $length = strlen($str);

    // 字符串长度小于等于4时，全部替换为*（避免逻辑错误）
    if ($length <= 4) {
        return str_repeat('*', $length);
    }

    // 计算左侧保留长度（总长度-4的一半，向下取整）
    $leftLength = floor(($length - 4) / 2);
    $left = substr($str, 0, $leftLength);
    $right = substr($str, $leftLength + 4);

    return $left . '****' . $right;
}
